﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace EAV.Bridge
{
    class SQLBuilder
    {
        const string QUERY_FORMAT = "SELECT VALUE e FROM EAVContext.Entity AS e WHERE e.IsDeleted = false AND e in ({0})";
        const string FILTER_FORMAT = "(SELECT VALUE v.Entity FROM EAVContext.Value AS v WHERE (v.Name = '{0}' AND v.{1} {2} {3}))";
        
        public static string GetSql(FilterMode mode, params Filter[] filters)
        {
            string[] sqlFragments = new string[filters.Length];

            for (int i = 0; i < filters.Length; i++)
            {
                sqlFragments[i] = Filter2Sql(filters[i]);
            }

            switch (mode)
            {
                case FilterMode.And:
                    return string.Format(QUERY_FORMAT, string.Join(" intersect ", sqlFragments));
                case FilterMode.Or:
                    return string.Format(QUERY_FORMAT, string.Join(" union ", sqlFragments));
                default:
                    return string.Empty;
            } 
           
            
        }

        private static string Filter2Sql(Filter filter)
        {
            return string.Format(FILTER_FORMAT,
                filter.Name,
                ParseField(filter.Value),
                filter.Operator,
                ParseValue(filter.Value)
                );
        }
        private static string ParseValue(object value)
        {
            if (value is string)
                return string.Format("'{0}'", value);
            else if (value is double)
                return ((double)value).ToString(CultureInfo.InvariantCulture);
            else if (value is float)
                return ((float)value).ToString(CultureInfo.InvariantCulture);
            else if (value is int)
                return value.ToString();
            else if (value is Guid)
                return string.Format("GUID'{0}'", value);
            else if (value is DateTime)
                return ((DateTime)value).ToString(CultureInfo.InvariantCulture);
            else
                return string.Empty;
        }
        private static string ParseField(object value)
        {
            if (value is string)
                return "StringValue";
            else if (value is double)
                return "NumericValue";
            else if (value is float)
                return "NumericValue";
            else if (value is int)
                return "IntValue";
            else if (value is Guid)
                return "GuidValue";
            else if (value is DateTime)
                return "DateTimeValue";
            else
                return string.Empty;
        }
    }
}
